package com.nineclock.attendance.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.attendance.config.PunchUtils;
import com.nineclock.attendance.dto.AttendGroupDTO;
import com.nineclock.attendance.dto.AttendPunchDTO;
import com.nineclock.attendance.mapper.AttendPunchMapper;
import com.nineclock.attendance.pojo.AttendPunch;
import com.nineclock.attendance.service.AttendGroupService;
import com.nineclock.attendance.service.AttendPunchService;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.DateTimeUtil;
import com.nineclock.system.feign.OrganizationFeign;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class AttendPunchServiceImpl implements AttendPunchService {
    @Autowired
    AttendPunchMapper attendPunchMapper;

    @Autowired
    AttendGroupService attendGroupService;

    @Autowired
    OrganizationFeign organizationFeign;
    @Override
    public void addPunch(AttendPunchDTO attendPunchDTO) {
        if(attendPunchDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //获取考勤组对象
        AttendGroupDTO attendGroupDTO = attendGroupService.getAttendGroupByUserId();

        //把dto转换为pojo
        AttendPunch attendPunch = BeanHelper.copyProperties(attendPunchDTO, AttendPunch.class);

        //设置基础信息
        attendPunch.setCompanyId(CurrentUserHolder.get().getCompanyId());
        attendPunch.setCompanyUserId(CurrentUserHolder.get().getCompanyUserId());
        attendPunch.setLat(new BigDecimal(attendPunchDTO.getLat()));
        attendPunch.setLng(new BigDecimal(attendPunchDTO.getLng()));
        attendPunch.setPunchTime(new Date());
        attendPunch.setPunchDateStr(DateUtil.format(new Date(), "yyyy-MM-dd")); //打卡时间 日期（年月日）
        attendPunch.setCreateTime(new Date());
        //上、下午打卡
        attendPunch.setPunchOnOffWork(DateTimeUtil.noonType(new Date()) + 1);

        //是否工作日打卡
        boolean validateWorkDay = PunchUtils.validateWorkDay(attendGroupDTO);
        if(!validateWorkDay){
            throw new NcException(ResponseEnum.PUNCH_INVALID_DAY);
        }


        //是否在有效范围打卡
        boolean flag = PunchUtils.validatePunchArea(attendPunchDTO, attendGroupDTO);
        if(! flag){
            throw new NcException(ResponseEnum.PUNCH_INVALID_AREA);
        }
        attendPunch.setAreaValid(flag);

        //是否有效打卡
        boolean effectiveValid = this.validatePunch(attendPunch);
//        attendPunch.setEffectiveValid(effectiveValid);
        if(effectiveValid){
            //设置打卡类型
            PunchUtils.setPunchType(attendPunch, attendGroupDTO);
        }

        attendPunchMapper.insert(attendPunch);
    }
    private boolean validatePunch(AttendPunch attendPunch) {
        LambdaQueryWrapper<AttendPunch> punchQw = new LambdaQueryWrapper<>();

        punchQw.eq(AttendPunch::getPunchOnOffWork, attendPunch.getPunchOnOffWork());
        punchQw.eq(AttendPunch::getCompanyId, CurrentUserHolder.get().getCompanyId());
        punchQw.eq(AttendPunch::getCompanyUserId, CurrentUserHolder.get().getCompanyUserId());
        punchQw.eq(AttendPunch::getPunchDateStr , attendPunch.getPunchDateStr());

        //查询 上/下午 打卡次数
        Integer count = attendPunchMapper.selectCount(punchQw);
        //如果 打卡次数为0 ， 无论何时打卡都是有效打卡
        if(count == 0){
            attendPunch.setEffectiveValid(true);
        }else{
            //如果打卡次数不为0， 且是上午打卡 ， 所以打卡无效
            if(attendPunch.getPunchOnOffWork() == 1){
                attendPunch.setEffectiveValid(false);
            }else{
                //否则 下午打卡，且次数不为0， 本次打卡有效
                attendPunch.setEffectiveValid(true);
                //更新下午其他的打卡为无效打卡
                AttendPunch updateAttendPunch = new AttendPunch();
                updateAttendPunch.setEffectiveValid(false);
                attendPunchMapper.update(updateAttendPunch, punchQw);
            }
        }

        return attendPunch.getEffectiveValid();
    }


    class MyColumnStyle extends AbstractColumnWidthStyleStrategy {
        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList,
                                      Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
            writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), 4500);
        }
    }
}
